#include "core.h"
#include "xGUID.h"
#include "GlobalConfig.h"

#ifdef WIN32
#include <Rpc.h>
#endif

CGuidCollector::CGuidCollector()
: m_nCurId(0)
, m_nMaxId(0xFFFFFF)
{
	m_IDList.reserve(20000);
}

CGuidCollector::~CGuidCollector()
{

}

U32 CGuidCollector::GenID()
{
	UINT new_id = 0;

	if ( m_IDList.size() < 10000 )
	{
		new_id = ++ m_nCurId;
	}
	else
	{
		new_id = *m_IDList.begin();
		m_IDList.erase(m_IDList.begin());
	}

	return new_id;
}

void CGuidCollector::FreeID(U32 n_id)
{
	m_IDList.push_back(n_id);
}

//------------------------------------------------------------------------------------------------
IMP_SINGLETON_CLASS(CGuidMgr)

CGuidMgr::CGuidMgr()
{

}

CGuidMgr::~CGuidMgr()
{

}

U32 CGuidMgr::GenHashUUID()
{
#ifdef WIN32
	U8 Uuid[ sizeof( UUID ) ];
	RPC_STATUS ret = UuidCreate( ( UUID * )&Uuid );
	if ( ret != RPC_S_OK ) 
	{
		memset(Uuid, 0, sizeof(Uuid));
	}
	U32 nHash = 0;
	const U8* pch = Uuid;
	U32 i;
	for ( i = 0; i < sizeof(Uuid); ++i )
	{
		nHash = (nHash<<5)+nHash+(*pch);
		pch++;
	}

	return ( nHash );
#else
	ASSERT( "GenHashUUID() not available for other" );
#endif
}

CGuidMgr::_X_GUID CGuidMgr::GenHighGUID(U32 EntityType)
{
	CCfgBase* pCfgBase = CClobalConfigMgr::getInstance()->mpCfgBase;

	CGuidMgr::_X_GUID ret;
	ret.SrvID = pCfgBase->mSrvID;
	ret.SrvType = pCfgBase->mNodeCard;
	ret.SrvIndex = pCfgBase->mSrvIndex;
	ret.EntityType = EntityType;
	ret.uID = 0;

	return ret;
}

CGuidMgr::_X_GUID CGuidMgr::GenGUID(U32 EntityType, U32 parameter)
{
	CGuidMgr::_X_GUID ret = GenHighGUID(EntityType);
	if ((EntityType == CGuidMgr::ENTITY_USER)
		|| (EntityType == CGuidMgr::ENTITY_ROLE)
		)
	{
		ret.uID = GenHashUUID();
	}
	else if (EntityType == CGuidMgr::ENTITY_STATIC_ROOM)
	{
		ret.uID = parameter;
	}
	else
	{
		ret.uID = GenID();
	}

	return ret;
}

void CGuidMgr::FreeID(U64 uGuid)
{
	CGuidMgr::_X_GUID x;
	x.xGuid = uGuid;
	if ((x.EntityType == CGuidMgr::ENTITY_USER)
		|| (x.EntityType == CGuidMgr::ENTITY_ROLE)
		|| (x.EntityType == CGuidMgr::ENTITY_STATIC_ROOM)
		)
	{
		;
	}
	else
	{
		m_idCollector.FreeID(x.uID);
	}
}